package com.qys.livesMall.financial.task;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qys.livesMall.app.user.model.dto.sys.SysUserBalanceChangeDTO;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.model.enums.UserBalanceLogTypeEnum;
import com.qys.livesMall.app.user.service.IH2AppUserBalanceService;
import com.qys.livesMall.app.user.service.IH2AppUserService;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.utils.DateUtils;
import com.qys.livesMall.financial.model.dto.OnlineSettlementContext;
import com.qys.livesMall.financial.model.dto.UserIncome;
import com.qys.livesMall.financial.model.entity.FinancialOnlineDetail;
import com.qys.livesMall.financial.model.entity.FinancialOnlineSettlementInfo;
import com.qys.livesMall.financial.model.entity.FinancialOnlineUser;
import com.qys.livesMall.financial.service.FinancialOnlineDetailService;
import com.qys.livesMall.financial.service.FinancialOnlineUserService;
import com.qys.livesMall.system.model.vo.sys.H2SysShareConfigVO;
import com.qys.livesMall.system.service.SysShareConfigService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 线上理财
 */
@SuppressWarnings({"DataFlowIssue", "NonAsciiCharacters"})
@Component("OnlineFinancialTask")
@Slf4j
@AllArgsConstructor
public class OnlineFinancialTask {

    private final IH2AppUserBalanceService userBalanceService;
    private final FinancialOnlineDetailService onlineDetailService;
    private final IH2AppUserService userService;
    private final FinancialOnlineUserService financialOnlineUserService;
    private final SysShareConfigService shareConfigService;

    private final SettlementTX settlementTX;
    private static final ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);



    /**
     * 更新理财产品收益 (每天凌晨 0点10分 执行)
     */

    public void updateEarnings() {
        List<FinancialOnlineDetail> onlineFinancialRecords = onlineDetailService.list(Wrappers.<FinancialOnlineDetail>lambdaQuery()
                .select(FinancialOnlineDetail::getId,
                        FinancialOnlineDetail::getUserId,
                        FinancialOnlineDetail::getOnlineFinancialId,
                        FinancialOnlineDetail::getAmount,
                        FinancialOnlineDetail::getInterestRate,
                        FinancialOnlineDetail::getPeriod,
                        FinancialOnlineDetail::getStartTime,
                        FinancialOnlineDetail::getEndTime,
                        FinancialOnlineDetail::getStatus,
                        FinancialOnlineDetail::getOrderNo)
                .eq(FinancialOnlineDetail::getStatus, 1));
        if (CollectionUtils.isEmpty(onlineFinancialRecords)) {
            return;
        }
        List<H2SysShareConfigVO> list = shareConfigService.list((byte) 1);
        if (list==null){
            list=new ArrayList<>();
        }

        for (FinancialOnlineDetail financialRecord : onlineFinancialRecords) {
            List<H2SysShareConfigVO> finalList = list;
            pool.execute(() -> {
                try {
                    OnlineSettlementContext context=new OnlineSettlementContext();
                    context.setUserId(String.valueOf(financialRecord.getUserId()));
                    context.setSuperIncomeConfig(finalList);
                    context.setStatus(true);
                    context.setDetail(financialRecord);

                    daySettlement(context);
                }catch (Exception e){
                    log.error("结算失败：id:{}",financialRecord.getId());
                    log.error("结算失败：",e);
                }
            });

        }
    }

    public void daySettlement(OnlineSettlementContext context){
        //当日无收益明细，判断是否是结算日
        LocalDateTime toDay=context.getDetail().getEndTime().plusDays(1);
        if (LocalDateTimeUtil.isSameDay(LocalDateTime.now(),toDay)||LocalDateTime.now().isAfter(toDay)){
            // 结算理财
            context.setStatus(true);
            //设置上级分成信息
            superiorIncome(context);
            //计算收益
            calculateBenefits(context);
            //落库
            settlementTX.settlement(context);
        }else {
            //不结算
            context.setStatus(false);
            upDayIncomeStatus(context);

        }

    }

    //修改日收益状态
    private void upDayIncomeStatus(OnlineSettlementContext context){
        //遍历添加每条的收益信息
        LambdaQueryWrapper<FinancialOnlineUser> query = new LambdaQueryWrapper<>();
        query.eq(FinancialOnlineUser::getFinancialOrderId, context.getDetail().getId());
//        query.eq(FinancialOnlineUser::getSettlementStatus,Constants.YesNoInt.NO);
        query.eq(FinancialOnlineUser::getIncomeDate,LocalDate.now());
        query.orderByAsc(FinancialOnlineUser::getIncomeDate);
        query.last("limit 1");
        FinancialOnlineUser financialOnlineUser=financialOnlineUserService.getOne(query);

        if (financialOnlineUser==null){
            if (LocalDateTime.now().isBefore(context.getDetail().getStartTime())){
                //当前时间在收益时间之前，不操作
                return;
            }
            log.warn("结算理财：id:{},未找到收益明细",context.getDetail().getId());
            //修复数据
            financialOnlineUser=new FinancialOnlineUser();
            financialOnlineUser.setUserId(context.getDetail().getUserId());
            financialOnlineUser.setAmount(context.getDetail().getAmount().multiply(context.getDetail().getInterestRate()));
            financialOnlineUser.setIncomeDate(LocalDate.now());
            financialOnlineUser.setSettlementStatus(Constants.YesNoInt.YES);
            financialOnlineUser.setFinancialOrderId(context.getDetail().getId());

            financialOnlineUserService.save(financialOnlineUser);
        }else {
            //更新状态
            if(Objects.equals(financialOnlineUser.getSettlementStatus(), Constants.YesNoInt.NO)){
                financialOnlineUser.setSettlementStatus(Constants.YesNoInt.YES);
                financialOnlineUserService.updateById(financialOnlineUser);
            }

        }
    }
    //计算收益
    private void calculateBenefits(OnlineSettlementContext context){
        FinancialOnlineSettlementInfo settlementInfo=new FinancialOnlineSettlementInfo();
        settlementInfo.setUserId(Long.valueOf(context.getUserId()));
        settlementInfo.setOnlineDetailId(context.getDetail().getId());
        settlementInfo.setPrincipal(context.getDetail().getAmount());
        settlementInfo.setTotalIncome(context.getDetail().getAmount().multiply(context.getDetail().getInterestRate()).multiply(new BigDecimal(context.getDetail().getPeriod().toString())).setScale(4, RoundingMode.DOWN));
        settlementInfo.setTotalRevenue(settlementInfo.getPrincipal().add(settlementInfo.getTotalIncome()));
        //上级收益
        BigDecimal superCommission = new BigDecimal("0");
        for(UserIncome userIncome:context.getUserIncomes()){
            if (Objects.equals(userIncome.getUserStatus(), Constants.YesNoInt.NO)){
                userIncome.setIncome(new BigDecimal("0"));
                continue;
            }
            userIncome.setIncome(settlementInfo.getTotalIncome().multiply(userIncome.getDividendRatio()).setScale(4, RoundingMode.DOWN));
            superCommission=superCommission.add(userIncome.getIncome());
        }
        settlementInfo.setSuperiorCommission(superCommission);
        settlementInfo.setSuperiorCommissionDetail(JSONObject.toJSONString(superCommission));
        //个人收益
        settlementInfo.setIncome(settlementInfo.getTotalIncome().subtract(settlementInfo.getSuperiorCommission()));

        context.setSettlementInfo(settlementInfo);
    }

    private void superiorIncome(OnlineSettlementContext context){
        List<UserIncome> superiorInfos=new ArrayList<>();
        context.setUserIncomes(superiorInfos);
        H2AppUser user=userService.getById(context.getUserId());

        Long superiorUserId=user.getSuperior();
        for(H2SysShareConfigVO sysShareConfig:context.getSuperIncomeConfig()){
            if (superiorUserId==null){
                break;
            }
            H2AppUser superUser=userService.getById(String.valueOf(superiorUserId));
            if (superUser==null){
                break;
            }
            UserIncome income=new UserIncome();
            income.setUserId(superUser.getId());
            income.setHierarchy(sysShareConfig.getHierarchy());
            income.setDividendRatio(sysShareConfig.getDividendRatio());
            //用户状态不正常，不参与分成
            if (!Objects.equals(superUser.getDeleted(), true)&&!Objects.equals(superUser.getStatus(), Constants.YesNoInt.YES)) {
                superiorUserId=superUser.getSuperior();
                income.setUserStatus(Constants.YesNoInt.YES);
            }else {
                superiorUserId=superUser.getSuperior();
                income.setUserStatus(Constants.YesNoInt.NO);
            }
            superiorInfos.add(income);
        }
    }
//
//    private boolean checkIncome(OnlineSettlementContext context ){
//        LambdaQueryWrapper <FinancialOnlineUser> query = new LambdaQueryWrapper<>();
//        query.select(FinancialOnlineUser::getIncomeDate,FinancialOnlineUser::getSettlementStatus);
//        query.eq(FinancialOnlineUser::getFinancialOrderId, context.getDetail().getId());
//        query.orderByAsc(FinancialOnlineUser::getIncomeDate);
//        List<FinancialOnlineUser> financialOnlineUsers=financialOnlineUserService.list(query);
//        if (CollectionUtils.isEmpty(financialOnlineUsers)){
//            log.error("结算理财失败：id:{},未找到收益明细",context.getDetail().getId());
//            context.getDetail().setSettlementDesc("结算理财失败,未找到收益明细");
//            return false;
//        }
//        for (FinancialOnlineUser onlineUser:financialOnlineUsers){
//            if (Objects.equals(onlineUser.getSettlementStatus(), Constants.YesNoInt.NO)){
//                if (context.getDetail().getEndTime().toLocalDate().isAfter(onlineUser.getIncomeDate())){
//                    //修复状态
//                    log.error("理财明细状态错误，id:{}",onlineUser.getId());
//                }else{
//                    //还未到结算时间
//                    log.error("理财明细日期错误，未达到结算日期。id:{}",onlineUser.getId());
//                    context.getDetail().setSettlementDesc("结算理财失败,未找到收益明细");
//                    return false;
//                }
//            }
//        }
//        context.getDetail().setStatus((byte) 2);
//        return true;
//    }





}
